Skip to main content

Interactive Manipulation

ManipulatePlot

An example of a built-in function for interactive plotting

Download original notebook
ManipulatePlot[{
  (*TB[*)Sum[(*|*)(*FB[*)((Sin[2π(2j - 1) x])(*,*)/(*,*)(2j-1))(*]FB*)(*|*), {(*|*)j(*|*),(*|*)1.0(*|*),(*|*)n(*|*)}](*|*)(*1:eJxTTMoPSmNiYGAoZgMSwaW5TvkVmYwgPguQCCkqTQUAeAcHBQ==*)(*]TB*),
  (*TB[*)Sum[(*|*)(*FB[*)((Cos[2π(2j - 1) x])(*,*)/(*,*)(2j-1))(*]FB*)(*|*), {(*|*)j(*|*),(*|*)1.0(*|*),(*|*)n(*|*)}](*|*)(*1:eJxTTMoPSmNiYGAoZgMSwaW5TvkVmYwgPguQCCkqTQUAeAcHBQ==*)(*]TB*)
  
}, {x, -1,1}, {{n,4}, 1,7, 1}]
(*VB[*)(FrontEndRef["f85ab492-742a-44ef-a938-1b1ae033b4ed"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp1mYJiaZWBrpmpsYJeqamKSm6SZaGlvoGiYZJqYaGBsnmaSmAACEOhXN"*)(*]VB*)

One can perform side effects using an optional parameter

Module[{r},
  ManipulatePlot[{
    (*TB[*)Sum[(*|*)(*FB[*)((Sin[2π(2j - 1) x])(*,*)/(*,*)(2j-1))(*]FB*)(*|*), {(*|*)j(*|*),(*|*)1.0(*|*),(*|*)n(*|*)}](*|*)(*1:eJxTTMoPSmNiYGAoZgMSwaW5TvkVmYwgPguQCCkqTQUAeAcHBQ==*)(*]TB*),
    (*TB[*)Sum[(*|*)(*FB[*)((Cos[2π(2j - 1) x])(*,*)/(*,*)(2j-1))(*]FB*)(*|*), {(*|*)j(*|*),(*|*)1.0(*|*),(*|*)n(*|*)}](*|*)(*1:eJxTTMoPSmNiYGAoZgMSwaW5TvkVmYwgPguQCCkqTQUAeAcHBQ==*)(*]TB*)
  
  }, {x, -1,1}, {{n,4}, 1,7, 1},
  Epilog -> {
    Table[{
      RandomColor[], Circle[RandomReal[{-1,1}, 2], r // Offload]
    }, {10}]
  }, "UpdateFunction" -> Function[n,
    r = (n - 1)/5.0;
    True
  ]]
]
(*VB[*)(FrontEndRef["045a1b78-b395-42f1-a374-615509f4284a"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKG5iYJhommVvoJhlbmuqaGKUZ6iYam5vomhmamhpYppkYWZgkAgB0CRSx"*)(*]VB*)

ManipulateParametricPlot is another variation:

ManipulateParametricPlot[Exp[-x/w]{Sin[x], Cos[x]}, {x,0,4Pi}, {w,10,100,10}]
(*VB[*)(FrontEndRef["35e7e2d9-981d-49cb-83a6-c3eb78defb50"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKG5ummqcapVjqWloYpuiaWCYn6VoYJ5rpJhunJplbpKSmJZkaAACHIxYX"*)(*]VB*)

General Manipulate expression

Manipulate can be used on any valid Wolfram Expression. 2D/3D plots and images passed as expr or part of it will be automatically optimized using Just-in-Time (JIT) transpiler if possible. This provides an immediate mode for a user to construct dynamic interactive widgets.

tip

For frequently changing data or complex visuals we still do recommend to use low-level building blocks such as Offload, InputRange.

Here is a basic example involving symbolics:

Manipulate[Column[{
  Style[StringTemplate["`` m/s"][x], Blue],
  Table["🚗", {i, Floor[x/25]}]//Row 
}], {x,10,100,10}, ContinuousAction->True]
(*VB[*)(FrontEndRef["f330fd25-a737-4dfc-ba88-07fcb85f8137"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKpxkbG6SlGJnqJpobm+uapKQl6yYlWljoGpinJSdZmKZZGBqbAwCKfxXe"*)(*]VB*)

Series expansion:

Manipulate[Series[Sin[x], {x,0,n}], {n,1,10,1}]
(*VB[*)(FrontEndRef["d8cf4b1d-225f-44ba-9d54-ebce09cf92bc"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp1gkp5kkGaboGhmZpumamCQl6lqmmJropiYlpxpYJqdZGiUlAwCTJxaU"*)(*]VB*)

More complex version:

Manipulate[Plot[1.0 + Sin[w] Sin[x + w],{x,0,5Pi}, Epilog->{
  Red, Point[{8.0, 1.0 + Sin[w] Sin[8.0 + w]}]
}], {w,0,Pi,0.3}, ContinuousAction->True]
(*VB[*)(FrontEndRef["4ee0e2e6-4808-4338-b866-0c23e7743e82"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKm6SmGqQapZrpmlgYWOiaGBtb6CZZmJnpGiQbGaeam5sYp1oYAQB74hTw"*)(*]VB*)

Another example, that solves ODE on-fly:

Manipulate[
 Plot[Evaluate[
   y[t] /. First[
     NDSolve[ {y''[x] == -x y[x], y[0] == a, y'[0] == b}, 
      y, {x, 0, 4}]]], {t, 0, 4}, 
  Epilog -> {Point[{4, 1/2}], Green, Arrow[{{0, a}, {1, b + a}}], Red,
     Point[{0, a}]},  PlotRange -> {{0,3},{-6,6}}],
 {{a, 1}, -3, 3, 1},
 {{b, 0}, -3, 3, 1}]
(*VB[*)(FrontEndRef["f9185179-d83d-40f0-8174-3b906206b2bf"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKp1kaWpgamlvqplgYp+iaGKQZ6FoYmpvoGidZGpgZGZglGSWlAQB0ZxTq"*)(*]VB*)

3D plot example:

Manipulate[Plot3D[Sin[n x] Cos[n y], {x,-1,1}, {y,-1,1}], {n, 1, 5, 0.3}, ContinuousAction->True]
(*VB[*)(FrontEndRef["bcee40c6-869e-44bb-99f0-9a89f826b35c"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKJyWnppoYJJvpWphZpuqamCQl6VpaphnoWiZaWKZZGJklGZsmAwCPZhXt"*)(*]VB*)

Image manipulations:

img = ImageResize[ExampleData[ExampleData["TestImage"] // Last], 200];
Manipulate[
  ImageAdjust[img, {c,a}], 
  
  {{c, 0},0,1,0.3}, 
  {{a, 0},0,1,0.3},
  ContinuousAction->True
]
(*VB[*)(FrontEndRef["90be4460-3a4c-42a0-8d2f-02c93dd20a60"])(*,*)(*"1:eJxTTMoPSmNkYGAoZgESHvk5KRCeEJBwK8rPK3HNS3GtSE0uLUlMykkNVgEKWxokpZqYmBnoGieaJOuaGCUa6FqkGKXpGhglWxqnpBgZJJoZAAB+ChVZ"*)(*]VB*)

Here is an example with mixed symbolics and graphics:

Manipulate[
  Row[{
    "m", "==", MatrixForm[m], 
    StreamPlot[Evaluate[m . {x, y}], {x, -1, 1}, {y, -1, 1}, 
      StreamScale -> Large, ImageSize -> Small
    ]
  }], {{m, ((*GB[*){{1(*|*),(*|*)0}(*||*),(*||*){0(*|*),(*|*)2}}(*]GB*))}, { ((*GB[*){{1(*|*),(*|*)0}(*||*),(*||*){0(*|*),(*|*)2}}(*]GB*)) -> "Nodal source",  ((*GB[*){{1(*|*),(*|*)1}(*||*),(*||*){0(*|*),(*|*)1}}(*]GB*))  -> "Degenerate source",  ((*GB[*){{0(*|*),(*|*)1}(*||*),(*||*){-1(*|*),(*|*)1}}(*]GB*)) -> "Spiral source",  ((*GB[*){{-1(*|*),(*|*)0}(*||*),(*||*){0(*|*),(*|*)-2}}(*]GB*))  -> "Nodal sink",  ((*GB[*){{-1(*|*),(*|*)1}(*||*),(*||*){0(*|*),(*|*)-1}}(*]GB*)) -> "Degenerate sink",  ((*GB[*){{0(*|*),(*|*)1}(*||*),(*||*){-1(*|*),(*|*)-1}}(*]GB*)) -> "Spiral sink",  ((*GB[*){{0(*|*),(*|*)1}(*||*),(*||*){-1(*|*),(*|*)0}}(*]GB*)) -> "Center",  ((*GB[*){{1(*|*),(*|*)0}(*||*),(*||*){0(*|*),(*|*)-2}}(*]GB*))  -> "Saddle"}}]

Tips for better performance

If you still want to use Manipulate on some complex expressions, there are some tricks to avoid deoptimization of JIT engine

tip
  • Try to keep the number of curves/traces/polygons expressions the same if possible. Try not to add new entities to your graphs.
  • PerformanceGoal->"Speed" is also a good option for 3D plots.
  • Mesh->None might also help.
  • PlotRange->Full can help to avoid fragmentation of line segments
  • Avoid changing colors, opacity at runtime
note

In any case you can still animate anything with a great performance using low-level building blocks Offload and AnimationFrameListener.

See Advanced section of the documentation

Fallback to Mathematica's Renderer

To use native Wolfram Language renderer, one can wrap Manipulate with MMAView. The output will be rasterized:

Manipulate[
  Plot3D[Sin[n x] Cos[n y], {x,-1,1}, {y,-1,1}]
, {n, 1, 5, 1}] // MMAView